package com.quanyan.ic.vendingMachine.http.service.impl;

import com.quanyan.ic.common.http.exception.BizException;
import com.quanyan.ic.common.spring.SpringUtil;
import com.quanyan.ic.vendingMachine.dao.VmUpgradeDao;
import com.quanyan.ic.vendingMachine.http.service.VmUpgradeService;
import com.quanyan.ic.vendingMachine.mapper.entity.VmUpgradeStatusEntity;
import com.quanyan.ic.vendingMachine.model.UpgradeVersionReq;
import com.quanyan.ic.vendingMachine.model.UpgradeVersionResp;
import com.quanyan.ic.vendingMachine.protocol.Cmd;
import com.quanyan.ic.vendingMachine.protocol.codec.protobuf.VmMessageBuilder;
import com.quanyan.ic.vendingMachine.protocol.codec.protobuf.VmMessageProto;
import com.quanyan.ic.vendingMachine.protocol.server.session.Session;
import com.quanyan.ic.vendingMachine.protocol.server.session.SessionManager;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * Created by Administrator on 2017/8/23.
 */
@Service
public class VmUpgradeServiceImpl implements VmUpgradeService{


    private static Logger logger = LoggerFactory.getLogger(VmOrderServiceImpl.class);
    @Value("${upgrade.file.basePath}")
    private String baseFileAddress; //上传下载basse地址
    @Autowired
    VmUpgradeDao vmUpgradeDao;
    @Override
    public UpgradeVersionResp getUpgradeInfo(UpgradeVersionReq req, HttpServletRequest request) {
        String fileType = req.getFileType();
        if (fileType == null) {
            throw new BizException("没有传入该类型文件");
        }
        UpgradeVersionResp upgrade = vmUpgradeDao.findUpgrade(fileType);
        String serverUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
        upgrade.setDownloadUrl(serverUrl+upgrade.getDownloadUrl());
        return upgrade;
    }





    /**
     * 上传文件插入数据
     * @param file
     * @param req
     */
    @Override
    public String uploadFileToType(MultipartFile file, UpgradeVersionResp req) {
    //    1上传文件
        if("vmc".equals(req.getFileType())){
            req.setFileType(req.getFileType()+"/yl/");
        }
        File targetPath = new File(baseFileAddress+ req.getFileType()+"/" +req.getName());
        if(targetPath.getParentFile().exists()){
            return  "上传失败";
        }
        try {
            file.transferTo(targetPath);
            //2.插入数据库
            req.setDownloadUrl("/larkic/vendingMachine/upgrade/download/"+req.getFileType()+"/" +req.getName());
            if(req.getIsUpgrade()==0)req.setIsUpgrade(1);
            vmUpgradeDao.insertFile(req);

            return "上传成功";
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "上传失败";
    }


    @Override
    public String  fileDownload(String fileType, String fileName, HttpServletResponse res){
        res.setHeader("content-type", "application/octet-stream");
        res.setContentType("application/octet-stream");
        res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            os = res.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(new File(baseFileAddress+"/"+fileType+"/"+fileName)));
            int i = bis.read(buff);
            while (i != -1) {
                os.write(buff, 0, buff.length);
                os.flush();
                i = bis.read(buff);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "下载失败";
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "下载成功";

    }


    @Override
    public String sendUpgradeCmd(UpgradeVersionReq req) {
        //1.发送推送指令
        boolean b = sendUpgradeCmd(req.getFileType(), req.getVmNumber());
        if(!b)
            return "推送失败,未找到设备";

        //2.关联vm_status表
        UpgradeVersionResp upgrade = vmUpgradeDao.findUpgrade(req.getFileType());
        VmUpgradeStatusEntity vmUpgradeStatusEntity = new VmUpgradeStatusEntity();
        vmUpgradeStatusEntity.setVmNumber(req.getVmNumber());
        vmUpgradeStatusEntity.setDownloadStatus(1);
        vmUpgradeStatusEntity.setFileType(req.getFileType());
        vmUpgradeStatusEntity.setNeedVersion(upgrade.getVersionCode());

        vmUpgradeDao.insertVmUpgradeStatus(vmUpgradeStatusEntity);
        return "推送成功";
    }

    /**
     * 售货机告诉更新成功
     * @param vmNumber
     * @param upgradeFileType
     */
    @Override
    public void updateUpgradeRecord(String vmNumber, String upgradeFileType,int status) {
        UpgradeVersionResp resp = vmUpgradeDao.findUpgrade(upgradeFileType);
        VmUpgradeStatusEntity vmUpgradeStatusEntity = new VmUpgradeStatusEntity();
        vmUpgradeStatusEntity.setVmNumber(vmNumber);
        vmUpgradeStatusEntity.setFileType(upgradeFileType);
        vmUpgradeStatusEntity.setNowVersion(resp.getVersionCode());
        vmUpgradeStatusEntity.setDownloadStatus(status);

        vmUpgradeDao.updateUpgradeRecord(vmUpgradeStatusEntity);
    }


    public boolean sendUpgradeCmd(String fileType, final String vmNumber) {
        SessionManager sessionManager = SpringUtil.getBean("sessionManager",SessionManager.class);
        Session session = sessionManager.get(vmNumber);
        if(session == null || session.getChannel() == null){
            logger.warn("---> send cmd [{}] to vm [{}], client offline", Cmd.UPGRADE_REQ.getDesc(),vmNumber);
            return false;
        }
        Channel channel = session.getChannel();
        final VmMessageProto.VmMessage vmMessage = new VmMessageBuilder(vmNumber)
                .buildCmd(Cmd.UPGRADE_REQ)
                .buildUpgradeFileType(fileType)
                .getMessage();
        ChannelFuture future  = channel.writeAndFlush(vmMessage);
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                logger.info("---> send cmd [{}] to vm [{}] completed, d={} c={} s={}， msg=\n{}",
                        Cmd.UPGRADE_REQ.getDesc(), vmNumber, channelFuture.isDone(), channelFuture.isCancelled(), channelFuture.isSuccess(), vmMessage);
            }
        });
        return true;
    }



}
